package com.tc.server;

import com.tc.msg.protocol.MessageCodeCSharable;
import com.tc.msg.protocol.ProcotolFrameDecoder;
import com.tc.server.handler.*;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @Auther: tianchao
 * @Date: 2022/2/14 15:15
 * @Description:
 */
@Slf4j
public class ChatServer {
    public static void main(String[] args) {
        new ChatServer().start();
    }

    void start(){
        LoginRequestMessageHandler LOGIN_HANDLER = new LoginRequestMessageHandler();   // 登录 处理
        QuitHandler QUIT_HANDLER = new QuitHandler();// 退出处理
        ChatRequestMessageHandler CHAT_REQUEST_MESSAGE_HANDLER = new ChatRequestMessageHandler();
        GroupCreateRequestMessageHandler GROUP_CREATE_REQUEST_MESSAGE_HANDLER = new GroupCreateRequestMessageHandler();
        GroupJoinRequestMessageHandler GROUP_JOIN_REQUEST_MESSAGE_HANDLER = new GroupJoinRequestMessageHandler();
        GroupMembersRequestMessageHandler GROUP_MEMBERS_REQUEST_MESSAGE_HANDLER = new GroupMembersRequestMessageHandler();
        GroupQuitRequestMessageHandler GROUP_QUIT_REQUEST_MESSAGE_HANDLER = new GroupQuitRequestMessageHandler();
        GroupChatRequestMessageHandler GROUP_CHAT_REQUEST_MESSAGE_HANDLER = new GroupChatRequestMessageHandler();
        LoggingHandler loggingHandler = new LoggingHandler(LogLevel.DEBUG);
        //MessageCodeC messageCodeC = new MessageCodeC();
        MessageCodeCSharable messageCodeC = new MessageCodeCSharable();
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.group(boss,worker);
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {

                    // 用来判断 是不是读 空闲时间过长，或写空闲时间过长 (读，写，读写空闲时间限制) 0表示不关心
                    // 12s内 如果没有收到channel的数据，则会触发一个事件
                    ch.pipeline().addLast(new IdleStateHandler(12, 0, 0));
                    /*
                    ################################################################
                    #####  ChannelDuplexHandler 可以同时作为 入站 和 出站处理器  #######
                    ##### 12 秒内 没读到数据 触发   IdleState.READER_IDLE       #######
                    #####       写         触发   IdleState.WRITER_IDLE       #######
                    #####     读写         触发   IdleState.ALL_IDLE          #######
                    ################################################################
                     */
                    ch.pipeline().addLast(new ChannelDuplexHandler(){
                        // 【用来处理 读写之外的 特殊的事件】
                        @Override //-- 触发的用户事件 --
                        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                            IdleStateEvent event = (IdleStateEvent) evt;
                            // 是否 读超时
                            if (event.state() == IdleState.READER_IDLE) {
                                log.debug("==============================已经12秒没读到数据了！====================================");
                                ctx.channel().close();
                            }
                        }
                    });
                    ch.pipeline().addLast(QUIT_HANDLER);
                    ch.pipeline().addLast(new ProcotolFrameDecoder());
                    ch.pipeline().addLast(loggingHandler);
                    ch.pipeline().addLast(messageCodeC);
                    ch.pipeline().addLast(LOGIN_HANDLER);//--登录---处理器
                    ch.pipeline().addLast(CHAT_REQUEST_MESSAGE_HANDLER); //--单聊---处理器
                    ch.pipeline().addLast(GROUP_CREATE_REQUEST_MESSAGE_HANDLER); //--创建群聊---处理器
                    ch.pipeline().addLast(GROUP_CHAT_REQUEST_MESSAGE_HANDLER); //--群聊---处理器

                    //下面的有问题???
//                    ch.pipeline().addLast(GROUP_JOIN_REQUEST_MESSAGE_HANDLER);
//                    ch.pipeline().addLast(GROUP_MEMBERS_REQUEST_MESSAGE_HANDLER);
//                    ch.pipeline().addLast(GROUP_QUIT_REQUEST_MESSAGE_HANDLER);


                }
            });
            final ChannelFuture channelFuture = serverBootstrap.bind(8081).sync();
            channelFuture.channel().closeFuture().sync();
        }catch (InterruptedException e){
            log.error("server error {}", e);
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
            log.debug("final 释放");
        }

    }
}
